home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Aminet 28
/
Aminet 28 (1998)(GTI - Schatztruhe)[!][Dec 1998].iso
/
Aminet
/
dev
/
lang
/
fpcsrc.lha
/
fpc
/
compiler
/
psub.pas
< prev
next >
Wrap
Pascal/Delphi Source File
|
1998-09-24
|
56KB
|
1,526 lines
{
$Id: psub.pas,v 1.3.2.4 1998/08/22 10:23:00 florian Exp $
Copyright (c) 1998 by Florian Klaempfl, Daniel Mantoine
Does the parsing of the procedures/functions
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
****************************************************************************
}
unit psub;
interface
uses cobjects;
procedure compile_proc_body(const proc_names:Tstringcontainer;
make_global,parent_has_class:boolean);
procedure _proc_head(options : word);
procedure proc_head;
procedure unter_dec;
implementation
uses
globals,scanner,symtable,aasm,tree,pass_1,
types,hcodegen,files,verbose,systems,strings,link,import
{$ifdef GDB}
,gdb
{$endif GDB}
{ parser specific stuff }
,pbase,ptconst,pdecl,pexpr,pstatmnt
{ processor specific stuff }
{$ifdef i386}
,i386,cgai386,tgeni386,cgi386,aopt386
{$endif}
{$ifdef m68k}
,m68k,cga68k,tgen68k,cg68k
{$endif}
;
procedure formal_parameter_list;
{ handle_procvar needs the same changes }
var sc:Pstringcontainer;
s:string;
p:Pdef;
vs:Pvarsym;
hs1,hs2:string;
varspez:Tvarspez;
begin
consume(LKLAMMER);
inc(testcurobject);
repeat
if token=_VAR then
begin
consume(_VAR);
varspez:=vs_var;
end
else
if token=_CONST then
begin
consume(_CONST);
varspez:=vs_const;
end
else
varspez:=vs_value;
sc:=idlist;
if token=COLON then
begin
consume(COLON);
{ check for an open array }
if token=_ARRAY then
begin
if (varspez<>vs_const) and (varspez<>vs_var) then
begin
varspez:=vs_const;
Message(parser_e_illegal_open_parameter);
end;
consume(_ARRAY);
consume(_OF);
{ define range and type of range }
p:=new(Parraydef,init(0,-1,s32bitdef));
{ define field type }
Parraydef(p)^.definition:=single_type(hs1);
hs1:='array_of_'+hs1;
end
else
p:=single_type(hs1);
end
else
begin
{$ifndef UseNiceNames}
hs1:='$$$';
{$else UseNiceNames}
hs1:='var';
{$endif UseNiceNames}
p:=new(Pformaldef,init);
end;
s:=sc^.get;
hs2:=aktprocsym^.definition^.mangledname;
while s<>'' do
begin
aktprocsym^.definition^.concatdef(p,varspez);
{$ifndef UseNiceNames}
hs2:=hs2+'$'+hs1;
{$else UseNiceNames}
hs2:=hs2+tostr(length(hs1))+hs1;
{$endif UseNiceNames}
vs:=new(Pvarsym,init(s,p));
vs^.varspez:=varspez;
{ we have to add this
to avoid var param to be in registers !!!}
if (varspez=vs_var) or (varspez=vs_const) and
dont_copy_const_param(p) then
vs^.regable:=false;
aktprocsym^.definition^.parast^.insert(vs);
s:=sc^.get;
end;
dispose(sc,done);
aktprocsym^.definition^.setmangledname(hs2);
if token=SEMICOLON then
consume(SEMICOLON)
else
break;
until false;
dec(testcurobject);
consume(RKLAMMER);
end;
{ contains the real name of a procedure as it's typed }
{ (the pattern isn't upper cased) }
var realname:stringid;
procedure _proc_head(options : word);
var sp:stringid;
pd:Pprocdef;
paramoffset:longint;
hsymtab:Psymtable;
sym:Psym;
hs:string;
overloaded_level:word;
begin
if (options and pooperator) <> 0 then
begin
sp:=overloaded_names[optoken];
realname:=sp;
end
else
begin
sp:=pattern;
realname:=orgpattern;
consume(ID);
end;
{ method ? }
if (token=POINT) and not(parse_only) then
begin
consume(POINT);
getsym(sp,true);
sym:=srsym;
{ qualifier is class name ? }
if (sym^.typ<>typesym) or
(ptypesym(sym)^.definition^.deftype<>objectdef) then
Message(parser_e_class_id_expected);
{ used to allow private syms to be seen }
aktobjectdef:=pobjectdef(ptypesym(sym)^.definition);
sp:=pattern;
realname:=orgpattern;
consume(ID);
procinfo._class:=pobjectdef(ptypesym(sym)^.definition);
aktprocsym:=pprocsym(procinfo._class^.publicsyms^.search(sp));
aktobjectdef:=nil;
{ we solve this below }
if not(assigned(aktprocsym)) then
Message(parser_e_methode_id_expected);
end
else
begin
if not(parse_only) and
((options and (poconstructor or podestructor))<>0) then
Message(parser_e_constructors_always_objects);
aktprocsym:=pprocsym(symtablestack^.search(sp));
if lexlevel=1 then
{$ifdef UseNiceNames}
hs:=procprefix+'_'+tostr(length(sp))+sp
{$else UseNiceNames}
hs:=procprefix+'_'+sp
{$endif UseNiceNames}
else
{$ifdef UseNiceNames}
hs:=lowercase(procprefix)+'_'+tostr(length(sp))+sp;
{$else UseNiceNames}
hs:=procprefix+'_$'+sp;
{$endif UseNiceNames}
if not(parse_only) then
begin
{The procedure we prepare for is in the implementation
part of the unit we compile. It is also possible that we
are compiling a program, which is also some kind of
implementaion part.
We need to find out if the procedure is global. If it is
global, it is in the global symtable.}
if not assigned(aktprocsym) then
begin
{Search the procedure in the global symtable.}
aktprocsym:=Pprocsym(search_a_symtable(sp,
globalsymtable));
if assigned(aktprocsym) then
begin
{Check if it is a procedure.}
if typeof(aktprocsym^)<>typeof(Tprocsym) then
Message1(sym_e_duplicate_id,aktprocsym^.Name);
{The procedure has been found. So it is
a global one. Set the flags to mark
this.}
procinfo.flags:=procinfo.flags or
pi_is_global;
end;
end;
end;
end;
{ problem with procedures inside methods }
{$ifndef UseNiceNames}
if assigned(procinfo._class) and (pos('_$$_',procprefix)=0) then
hs:=procprefix+'_$$_'+procinfo._class^.name^+'_'+sp;
{$else UseNiceNames}
if assigned(procinfo._class) and (pos('_5Class_',procprefix)=0) then